# 项目子计划管理
from BlackWidow.tools import tools
from django import forms
from django.forms.models import model_to_dict
from BlackWidow.models import ProjectSubPlan, Project, User
from django.http import JsonResponse
from BlackWidow.apis.user.manage import model_to_dict_with_url as user_model_to_dict_with_url
from BlackWidow.apis.projects.Project import model_to_dict_with_time as project_model_to_dict_with_time

def model_to_dict_with_time(model):
    """
    将模型对象转换为字典，并处理时间字段
    Args:
        model: 模型对象
    Returns:
        dict: 处理后的字典数据
    """
    model_dict = model_to_dict(model)
    # 将子计划总负责人转换为字典
    model_dict['sub_plan_total_leader'] = user_model_to_dict_with_url(model.sub_plan_total_leader)
    # 将项目信息转换为字典
    model_dict['project'] = project_model_to_dict_with_time(model.project)
    model_dict['create_time'] = model.create_time.strftime('%Y-%m-%d %H:%M:%S')
    model_dict['update_time'] = model.update_time.strftime('%Y-%m-%d %H:%M:%S')
    # 添加子计划状态文本
    model_dict['sub_plan_status'] = {
        "name": model.get_sub_plan_status_display(),
        "id": model.sub_plan_status
    }
    return model_dict


class ProjectSubPlanModelForm(forms.ModelForm):
    """
    项目子计划表单类
    用于验证和处理项目子计划数据的表单
    """
    class Meta:
        model = ProjectSubPlan
        fields = [
            'project',
            'sub_plan_name',
            'sub_plan_description',
            'sub_plan_total_leader',
            'sub_plan_status'
        ]

    def clean_sub_plan_name(self):
        """
        子计划名称验证
        确保子计划名称符合要求
        """
        sub_plan_name = self.cleaned_data.get('sub_plan_name')
        if len(sub_plan_name) < 2:
            raise forms.ValidationError('子计划名称不能少于2个字符')
        if len(sub_plan_name) > 50:
            raise forms.ValidationError('子计划名称不能超过50个字符')
        return sub_plan_name

    def clean_sub_plan_status(self):
        """
        子计划状态验证
        确保子计划状态值有效
        """
        status = self.cleaned_data.get('sub_plan_status')
        valid_statuses = [choice[0] for choice in ProjectSubPlan.sub_plan_status_choice]
        if status not in valid_statuses:
            raise forms.ValidationError('无效的子计划状态')
        return status



# 创建子计划
def create_sub_plan(request):
    """
    创建项目子计划
    处理项目子计划创建请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        sub_plan_data = request.POST.copy()
        sub_plan_data['sub_plan_total_leader'] = request.user.user_id
        form = ProjectSubPlanModelForm(sub_plan_data)
        if form.is_valid():
            try:
                # 验证项目是否存在且用户是否有权限
                project = Project.objects.get(project_id=sub_plan_data['project'])
                if project.project_leader.user_id != request.user.user_id:
                    return JsonResponse(tools.ReturnData(1, '无权限创建子计划'))
                
                # 创建子计划
                form.save()
                sub_plan = form.instance
                
                # 返回子计划信息
                sub_plan_data = model_to_dict_with_time(sub_plan)
                return JsonResponse(tools.ReturnData(0, '创建成功', data=sub_plan_data))
            except Project.DoesNotExist:
                return JsonResponse(tools.ReturnData(1, '项目不存在'))
            except Exception as e:
                return JsonResponse(tools.ReturnData(1, f'创建失败: {str(e)}'))
        else:
            return JsonResponse(tools.ReturnData(1, '创建失败', tools.get_first_error(form)))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


# 更新子计划
def update_sub_plan(request):
    """
    更新项目子计划
    处理项目子计划更新请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        sub_plan_id = request.POST.get('sub_plan_id')
        if not sub_plan_id:
            return JsonResponse(tools.ReturnData(1, '子计划ID不能为空'))

        try:
            sub_plan = ProjectSubPlan.objects.get(sub_plan_id=sub_plan_id)
            # 验证是否是项目负责人或子计划负责人
            if (sub_plan.project.project_leader.user_id != request.user.user_id and 
                sub_plan.sub_plan_total_leader.user_id != request.user.user_id):
                return JsonResponse(tools.ReturnData(1, '无权限修改子计划'))
        except ProjectSubPlan.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '子计划不存在'))

        sub_plan_data = request.POST.copy()
        sub_plan_data['sub_plan_total_leader'] = request.user.user_id
        form = ProjectSubPlanModelForm(sub_plan_data, instance=sub_plan)
        if form.is_valid():
            try:
                # 更新子计划
                sub_plan = form.save()
                
                # 返回更新后的子计划信息
                sub_plan_data = model_to_dict_with_time(sub_plan)
                return JsonResponse(tools.ReturnData(0, '更新成功', data=sub_plan_data))
            except Exception as e:
                return JsonResponse(tools.ReturnData(1, f'更新失败: {str(e)}'))
        else:
            return JsonResponse(tools.ReturnData(1, '更新失败', tools.get_first_error(form)))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


# 更新子计划状态
def update_sub_plan_status(request):
    """
    更新项目子计划状态
    处理项目子计划状态更新请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        sub_plan_id = request.POST.get('sub_plan_id')
        sub_plan_status = request.POST.get('sub_plan_status')
        
        if not sub_plan_id:
            return JsonResponse(tools.ReturnData(1, '子计划ID不能为空'))
        if not sub_plan_status:
            return JsonResponse(tools.ReturnData(1, '子计划状态不能为空'))

        try:
            sub_plan = ProjectSubPlan.objects.get(sub_plan_id=sub_plan_id)
            # 验证是否是项目负责人或子计划负责人
            if (sub_plan.project.project_leader.user_id != request.user.user_id and 
                sub_plan.sub_plan_total_leader.user_id != request.user.user_id):
                return JsonResponse(tools.ReturnData(1, '无权限修改子计划状态'))
            
            # 验证状态值是否有效
            valid_statuses = [choice[0] for choice in ProjectSubPlan.sub_plan_status_choice]
            if int(sub_plan_status) not in valid_statuses:
                return JsonResponse(tools.ReturnData(1, '无效的子计划状态'))
            
            # 更新子计划状态
            sub_plan.sub_plan_status = int(sub_plan_status)
            sub_plan.save()
            
            # 返回更新后的子计划信息
            sub_plan_data = model_to_dict_with_time(sub_plan)
            return JsonResponse(tools.ReturnData(0, '状态更新成功', data=sub_plan_data))
        except ProjectSubPlan.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '子计划不存在'))
        except ValueError:
            return JsonResponse(tools.ReturnData(1, '子计划状态必须是数字'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'更新失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


# 删除子计划
def delete_sub_plan(request):
    """
    删除项目子计划
    处理项目子计划删除请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'POST':
        sub_plan_id = request.POST.get('sub_plan_id')
        if not sub_plan_id:
            return JsonResponse(tools.ReturnData(1, '子计划ID不能为空'))

        try:
            sub_plan = ProjectSubPlan.objects.get(sub_plan_id=sub_plan_id)
            # 验证是否是项目负责人或子计划负责人
            if (sub_plan.project.project_leader.user_id != request.user.user_id and 
                sub_plan.sub_plan_total_leader.user_id != request.user.user_id):
                return JsonResponse(tools.ReturnData(1, '无权限删除子计划'))
            sub_plan.delete()
            return JsonResponse(tools.ReturnData(0, '删除成功'))
        except ProjectSubPlan.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '子计划不存在'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'删除失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


# 获取子计划
def get_sub_plan(request):
    """
    获取项目子计划信息
    处理项目子计划查询请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'GET':
        sub_plan_id = request.GET.get('sub_plan_id')
        project_id = request.GET.get('project_id')
        sub_plan_status = request.GET.get('sub_plan_status')
        
        try:
            if sub_plan_id:
                # 获取单个子计划
                sub_plan = ProjectSubPlan.objects.get(sub_plan_id=sub_plan_id)
                sub_plan_data = model_to_dict_with_time(sub_plan)
                return JsonResponse(tools.ReturnData(0, '获取成功', data=sub_plan_data))
            elif project_id:
                # 获取指定项目的子计划列表
                sub_plans = ProjectSubPlan.objects.filter(project_id=project_id)
                
                # 如果指定了状态，则按状态筛选
                if sub_plan_status:
                    try:
                        sub_plan_status = int(sub_plan_status)
                        valid_statuses = [choice[0] for choice in ProjectSubPlan.sub_plan_status_choice]
                        if sub_plan_status not in valid_statuses:
                            return JsonResponse(tools.ReturnData(1, '无效的子计划状态'))
                        sub_plans = sub_plans.filter(sub_plan_status=sub_plan_status)
                    except ValueError:
                        return JsonResponse(tools.ReturnData(1, '子计划状态必须是数字'))
                
                # 按创建时间倒序排序
                sub_plans = sub_plans.order_by('-create_time')
                sub_plans_data = [model_to_dict_with_time(sub_plan) for sub_plan in sub_plans]
                return JsonResponse(tools.ReturnData(0, '获取成功', data=sub_plans_data))
            else:
                return JsonResponse(tools.ReturnData(1, '子计划ID或项目ID不能为空'))
        except ProjectSubPlan.DoesNotExist:
            return JsonResponse(tools.ReturnData(1, '子计划不存在'))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'获取失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))


# 获取用户负责的子计划列表
def get_user_sub_plans(request):
    """
    获取用户负责的子计划列表
    处理用户子计划查询请求
    Args:
        request: HTTP请求对象
    Returns:
        JsonResponse: 包含操作结果的JSON响应
    """
    if request.method == 'GET':
        sub_plan_status = request.GET.get('sub_plan_status')
        
        try:
            # 获取用户负责的子计划列表
            sub_plans = ProjectSubPlan.objects.filter(sub_plan_total_leader_id=request.user.user_id)
            
            # 如果指定了状态，则按状态筛选
            if sub_plan_status:
                try:
                    sub_plan_status = int(sub_plan_status)
                    valid_statuses = [choice[0] for choice in ProjectSubPlan.sub_plan_status_choice]
                    if sub_plan_status not in valid_statuses:
                        return JsonResponse(tools.ReturnData(1, '无效的子计划状态'))
                    sub_plans = sub_plans.filter(sub_plan_status=sub_plan_status)
                except ValueError:
                    return JsonResponse(tools.ReturnData(1, '子计划状态必须是数字'))
            
            # 按创建时间倒序排序
            sub_plans = sub_plans.order_by('-create_time')
            sub_plans_data = [model_to_dict_with_time(sub_plan) for sub_plan in sub_plans]
            return JsonResponse(tools.ReturnData(0, '获取成功', data=sub_plans_data))
        except Exception as e:
            return JsonResponse(tools.ReturnData(1, f'获取失败: {str(e)}'))
    else:
        return JsonResponse(tools.ReturnData(1, '请求方式错误'))

